feat(tracepoint): add sched_process_exec tracepoint#2154
Conversation
为 execve 成功路径添加 sched_process_exec tracepoint,供 ANOLISA agentsight 的 eBPF 程序追踪进程 exec 事件、构建 AI agent 进程树。 - 新增 kernel/src/process/trace.rs:声明 sched_process_exec tracepoint(comm/pid/old_pid 字段),TP_system(sched) - execve.rs:在 load_binary_file_with_context 之前捕获 old_pid(de_thread 会交换 pid);trace 调用置于 arch_do_execve 成功后、is_ok() 分支内,对齐 Linux fs/exec.c:1803 - mod.rs:注册 process::trace 模块 tracepoint 注册、debugfs 导出、eBPF attach 全部由现有框架自动完成。static key 保证未启用时零开销。 Refs: DragonOS-Community#2149 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>
新增 sched_tracepoint dunitest,验证 sched_process_exec tracepoint 的 debugfs 导出(format/enable/id 文件 + 字段)与 execve 触发行为。
- EventFilesExist: 验证 events/sched/sched_process_exec/{format,id,enable} 存在,format 含 comm/pid/old_pid/common_pid 字段
- FiresOnExecve: enable + 清空 trace 后 fork+execve(/proc/self/exe),断言 trace 含 sched_process_exec 记录与 comm 字段
- whitelist 注册 normal/sched_tracepoint
Refs: DragonOS-Community#2149
Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5b1c50988b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| TP_system(sched), | ||
| TP_PROTO(comm: &str, pid: i32, old_pid: i32), | ||
| TP_STRUCT__entry { | ||
| comm: [u8; 16], |
There was a problem hiding this comment.
保持 sched_process_exec 的 filename ABI
这里把事件 payload 定义成 comm 会让 /tracing/events/sched/sched_process_exec/format 暴露为 comm,pid,old_pid,而 Linux 6.6 的同名 tracepoint ABI 是 filename,pid,old_pid(filename 还是第一项,见 https://codebrowser.dev/linux/linux/include/trace/events/sched.h.html#431)。因此按 Linux format 编译或按 filename 过滤/解析的 eBPF/trace 工具会在 DragonOS 上找不到字段,raw offset 也会读错,恰好破坏本次为 agentsight 兼容该 tracepoint 的目的;即使暂时不能实现动态 __string,也应保留 filename 字段语义/名称并从 exec 参数填充。
Useful? React with 👍 / 👎.
| // sched_process_exec:arch_do_execve 成功、用户态寄存器就绪后触发, | ||
| // 对齐 Linux fs/exec.c:1803(trace 在 start_thread 之后、所有失败点之后)。 | ||
| let pid = pcb.raw_pid().data() as i32; | ||
| trace_sched_process_exec(pcb.basic().name(), pid, old_pid); |
There was a problem hiding this comment.
当 sched_process_exec 已启用且另一个 CPU 已在这个进程的 basic 锁上排队写锁时,pcb.basic().name() 产生的读锁 guard 会一直持有到 trace_sched_process_exec 返回;但默认 tracepoint callback 会在 kernel/src/tracepoint/basic_macro.rs 中调用 trace_cmdline_push(),它又对当前进程执行 process.basic() 读锁获取。DragonOS 的 RwLock 在有 pending writer 时会阻止新读者,所以当前 CPU 会等待 writer,而 writer 又等外层读锁释放,导致 exec 路径自旋卡死;应先把名称复制到局部并让 guard drop,或避免 trace 路径重入读取同一把锁。
Useful? React with 👍 / 👎.
TracePointIdFile 的 id 由 global_init_events 的 AtomicUsize::new(0) fetch_add 分配,从 0 开始递增。原断言 EXPECT_GT(idval, 0) 错误假设 id 从 1 开始,导致 CI 中拿到 id=0 的 tracepoint 失败。改为 EXPECT_GE(idval, 0)。 Refs: DragonOS-Community#2149 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>
…exec PR review 发现:trace_sched_process_exec(pcb.basic().name(), ...) 持有 basic 读锁 guard 直到 trace 调用返回,而 trace 默认回调内部的 trace_cmdline_push() 会再次获取同一把 basic 读锁。DragonOS RwLock 读锁不可重入,若此时另一 CPU 排队写锁,将导致 reader 等 writer、writer 等 reader 的 deadlock。 修复:先将 comm 复制到栈缓冲并在内层作用域释放读锁 guard,再调用 trace,消除锁重入。 Refs: DragonOS-Community#2149 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>
bug-hunter fanout 发现:comm_len = bytes.len().min(15) 在原始字节偏移截断,当进程名第 15 字节落在多字节 UTF-8 字符中间时(如 Unicode 路径名),from_utf8 失败导致 comm 变空字符串。用 is_char_boundary 回退到字符边界修复。 同时加强测试:strtol 解析 id 后校验 end 指针,确认整个字符串都是数字而非仅前缀可解析。 Refs: DragonOS-Community#2149 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>
|
感谢这两条 review,已逐条处理: ① trace.rs:14 — 保持 filename ABI(不采纳) 经 bug-hunter 多角色 fanout 审查(ABI 维度)独立确认:
因此「保留 ② execve.rs:226 — 先释放 basic 读锁再触发 tracepoint(采纳,已修复) 确认是真问题。 修复(commit 附带:fanout 的 EdgeCases 维度还发现我修锁时引入的一个回归——comm 截断在原始字节偏移,多字节 UTF-8 路径名(如 |
make fmt / clippy: name.as_bytes().len() → name.len()(字符串可直接调 len())。 Refs: DragonOS-Community#2149 Signed-off-by: sparkzky <sparkhhhhhhhhhh@outlook.com>
为 execve 成功路径添加
sched_process_exectracepoint,供 ANOLISA agentsight 的 eBPF 程序追踪进程 exec 事件、构建 AI agent 进程树。变更内容
kernel/src/process/trace.rs:声明sched_process_exectracepoint(comm/pid/old_pid字段),TP_system(sched)。字段参考 Linuxinclude/trace/events/sched.h。kernel/src/process/execve.rs:在load_binary_file_with_context之前捕获old_pid(de_thread会交换 pid);trace 调用置于arch_do_execve成功后、is_ok()分支内,对齐 Linuxfs/exec.cexec_binprm()中trace_sched_process_exec的调用位置。kernel/src/process/mod.rs:注册process::trace模块。设计说明
define_event_trace!宏不支持 Linux 的__string动态字符串,且当前未实现bpf_get_current_comm()helper,故comm直接放入 payload([u8; 16],对齐TASK_COMM_LEN)。TP_printk在首个 NUL 字节处截断 comm,使用 Display 格式输出,输出格式对齐 Linux 的comm=... pid=... old_pid=...。Refs: #2149